﻿#region Using Statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
#endregion

namespace TheSpirit
{
    class FieldScreen : GameScreen
    {
        #region Declaration

        GameTime gameTime;
        
        //덱에 있는 Fire Card
        List<Card> FireCard = new List<Card>();
        //덱에 있는 Water Card
        List<Card> WaterCard = new List<Card>();
        //덱에 있는 Forest Card
        List<Card> ForestCard = new List<Card>();
        //덱에 있는 Upgrade Card
        List<Card> UpgradeCard = new List<Card>();
        //설치된 카드
        List<Card> InstallCard = new List<Card>();
        //카드 개수 [FireBall] [WaterBall] [Grass] 
        Dictionary<String, int> cardCount = new Dictionary<String, int>();

        Map map;
        Tile[,] tile;
        Character character;
        ShortCutWindow shortCutWindow;
        InformationWindow informationWindow;

        int tileWidth;
        int tileHeight;
        int tileSizeX;
        int tileSizeY;

        Texture2D uiTexture;

        #endregion


        #region Initialize

        public FieldScreen()
        {
            LoadMap();
            character = new Character(0, 0);
            shortCutWindow = new ShortCutWindow();

            tileSizeX = 100;
            tileSizeY = 100;
        }

        public FieldScreen(Dictionary<String, int> cardCount)
        {
            LoadMap();
            character = new Character(13, 9);
            shortCutWindow = new ShortCutWindow();
            informationWindow = new InformationWindow();

            //타일의 크기 결정
            tileSizeX = 100;
            tileSizeY = 100;

            this.cardCount = cardCount;

            //기본 카드 추가
            for (int i = 0; i < cardCount["FireBall"]; i++)
            {
                FireCard.Add(new FireBallCard());
            }
            for (int i = 0; i < cardCount["WaterBall"]; i++)
            {
                WaterCard.Add(new WaterBallCard());
            }
            for (int i = 0; i < cardCount["Grass"]; i++)
            {
                ForestCard.Add(new GrassCard());
            }
            for (int i = 0; i < cardCount["Upgrade"]; i++)
            {
                UpgradeCard.Add(new UpgradeCard());
            }
        }

        public override void LoadContent()
        {
            ContentManager content = ScreenManager.Game.Content;

            uiTexture = content.Load<Texture2D>("Fields/playUI");

            shortCutWindow.LoadContent(content);
            map.LoadContent(content);
            character.LoadContent(content);
            LoadTile(content);
            map.SetTile(tile, content);
            informationWindow.LoadContent(content);
        }

        #endregion


        #region Update & Draw

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            this.gameTime = gameTime;
 	        base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
        }

        public override void HandleInput()
        {
            InputManager.ChangeMouseCursor("Normal");

            map.Update(gameTime, tileHeight, tileWidth, tile);
            character.Update(gameTime, map.WorldLocation.X, map.WorldLocation.Y, tile, tileHeight, tileWidth, map.OpenEnemy);
            SetTileLocation();

            shortCutWindow.Update(FireCard.Count, WaterCard.Count, ForestCard.Count, UpgradeCard.Count);
            informationWindow.Update(gameTime, character);

            //타워의 좌표 업데이트
            foreach (Card c in InstallCard)
            {
                int x = c.Tower.WorldLocation.X - map.WorldLocation.X;
                int y = c.Tower.WorldLocation.Y - map.WorldLocation.Y;

                c.Tower.LocalLocation = new Rectangle(x, y,
                    c.Tower.TowerTexture.Width,
                    c.Tower.TowerTexture.Height);

                c.Update(gameTime, map.OpenEnemy, map.WorldLocation.X, map.WorldLocation.Y);
            }

            if (InputManager.IsRightClicked())
            {
                shortCutWindow.IsSelectFire = false;
                shortCutWindow.IsSelectWater = false;
                shortCutWindow.IsSelectForest = false;
                shortCutWindow.IsSelectUpgrade = false;
            }
            if(InputManager.IsLeftClicked())
            {
                if (shortCutWindow.IsSelectFire || shortCutWindow.IsSelectWater || shortCutWindow.IsSelectForest)
                {
                    for (int i = 0; i < tileHeight; i++)
                    {
                        for (int j = 0; j < tileWidth; j++)
                        {
                            if (tile[i, j].InScreen && tile[i, j].tileState == Tile.TileState.Empty && tile[i,j].LocalLocation.Y >= 95)
                            {
                                if (InputManager.MousePosition.Intersects(tile[i, j].LocalLocation))
                                {
                                    if (shortCutWindow.IsSelectFire)
                                    {
                                        InstallCard.Add(FireCard[0]);
                                        InstallCard[InstallCard.Count - 1].Tower.TileLocation = new Point(i, j);
                                        CalculateTowerLocate(i, j);
                                        tile[i, j].tileState = Tile.TileState.Tower;
                                        FireCard.RemoveAt(0);
                                        shortCutWindow.IsSelectFire = false;
                                    }
                                    if (shortCutWindow.IsSelectWater)
                                    {
                                        InstallCard.Add(WaterCard[0]);
                                        InstallCard[InstallCard.Count - 1].Tower.TileLocation = new Point(i, j);
                                        CalculateTowerLocate(i, j);
                                        tile[i, j].tileState = Tile.TileState.Tower;
                                        WaterCard.RemoveAt(0);
                                        shortCutWindow.IsSelectWater = false;
                                    }
                                    if (shortCutWindow.IsSelectForest)
                                    {
                                        InstallCard.Add(ForestCard[0]);
                                        InstallCard[InstallCard.Count - 1].Tower.TileLocation = new Point(i, j);
                                        CalculateTowerLocate(i, j);
                                        tile[i, j].tileState = Tile.TileState.Tower;
                                        ForestCard.RemoveAt(0);
                                        shortCutWindow.IsSelectForest = false;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        public override void Draw(GameTime gameTime)
        {
            Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;

            spriteBatch.Begin();

            map.Draw(spriteBatch);
            TileDraw(spriteBatch);
            character.Draw(gameTime, spriteBatch);

            foreach (Card c in InstallCard)
            {
                c.Tower.Draw(spriteBatch);
            }

            spriteBatch.Draw(uiTexture, new Rectangle(0, 0, Constants.WIDTH, Constants.HEIGHT), Color.White);
            shortCutWindow.Draw(spriteBatch);
            informationWindow.Draw(spriteBatch);

            TowerShadowDraw(spriteBatch);
            
            spriteBatch.End();
        }

        public void TileDraw(SpriteBatch spriteBatch)
        {
            for (int i = 0; i < tileHeight; i++)
            {
                for (int j = 0; j < tileWidth; j++)
                {
                    if ((tile[i, j].LocalLocation.X + tile[i, j].LocalLocation.Width) > Constants.SCREENX && tile[i, j].LocalLocation.X < Constants.SCREENWIDTH &&
                        tile[i, j].LocalLocation.Y + tile[i, j].LocalLocation.Height > Constants.SCREENY && tile[i, j].LocalLocation.Y < Constants.WIDTH)
                    {
                        tile[i, j].InScreen = true;
                        tile[i, j].Draw(spriteBatch);
                    }
                    else
                        tile[i, j].InScreen = false;
                }
            }
        }

        #endregion


        #region Helper
        //설치될 위치 표시
        public void TowerShadowDraw(SpriteBatch spriteBatch)
        {
            ContentManager content = ScreenManager.Game.Content;

            for (int i = 0; i < tileHeight; i++)
            {
                for (int j = 0; j < tileWidth; j++)
                {
                    if (tile[i, j].InScreen && tile[i, j].tileState == Tile.TileState.Empty)
                    {
                        if (InputManager.MousePosition.Intersects(tile[i, j].LocalLocation))
                        {
                            if (shortCutWindow.IsSelectFire)
                            {
                                Texture2D texture = content.Load<Texture2D>("Tower/Fire/FireBallTower");

                                int x = tile[i, j].LocalLocation.X + (tile[i, j].WorldLocation.Width -
                                    texture.Width) / 2;
                                int y = tile[i, j].LocalLocation.Y + tile[i, j].WorldLocation.Height -
                                    texture.Height;
                                int w = texture.Width;
                                int h = texture.Height;
                                
                                spriteBatch.Draw(texture, new Rectangle(x, y, w, h), Color.White * 0.5f);

                                return;
                            }
                            if (shortCutWindow.IsSelectWater)
                            {
                                Texture2D texture = content.Load<Texture2D>("Tower/Water/WaterBallTower");

                                int x = tile[i, j].LocalLocation.X + (tile[i, j].WorldLocation.Width -
                                    texture.Width) / 2;
                                int y = tile[i, j].LocalLocation.Y + tile[i, j].WorldLocation.Height -
                                    texture.Height;
                                int w = texture.Width;
                                int h = texture.Height;

                                spriteBatch.Draw(texture, new Rectangle(x, y, w, h), Color.White * 0.5f);

                                return;
                            }
                            if (shortCutWindow.IsSelectForest)
                            {
                                Texture2D texture = content.Load<Texture2D>("Tower/Forest/GrassTower");

                                int x = tile[i, j].LocalLocation.X + (tile[i, j].WorldLocation.Width -
                                    texture.Width) / 2;
                                int y = tile[i, j].LocalLocation.Y + tile[i, j].WorldLocation.Height -
                                    texture.Height;
                                int w = texture.Width;
                                int h = texture.Height;

                                spriteBatch.Draw(texture, new Rectangle(x, y, w, h), Color.White * 0.5f);

                                return;
                            }
                        }
                    }
                }
            }
        }
        //스테이지에 따른 맵의 설정
        public void LoadMap()
        {
            switch(Constants.Stage)
            {
                case Constants.STAGE.stage01:
                    map = new Map000();
                    break;
            }
        }
        //타일 위치 설정 , 타일 시작 위치
        public void LoadTile(ContentManager content)
        {
            int length = 0;

            tileWidth = (map.BackgroundTexture.Width - 2 * length) / tileSizeX;
            tileHeight = (map.BackgroundTexture.Height - 2 * length) / tileSizeY;

            tile = new Tile[tileHeight, tileWidth];

            //타일의 시작 위치
            int x = Constants.SCREENX + length, y = Constants.SCREENY + length;

            for (int i = 0; i < tileHeight; i++)
            {
                x = Constants.SCREENX + length;

                for (int j = 0; j < tileWidth; j++)
                {
                    tile[i, j] = new Tile(x, y, tileSizeX, tileSizeY);
                    tile[i, j].TileLocation = new Point(i, j);
                    x += tileSizeX;
                }
                y += tileSizeY;
            }
            Tile.LoadContent(content);
            //캐릭터 위치 설정
            character.SetTile(tile);
        }
        //화면에 출력할 타일의 위치를 설정
        public void SetTileLocation()
        {
            for (int i = 0; i < tileHeight; i++)
            {
                for (int j = 0; j < tileWidth; j++)
                {
                    tile[i, j].setLocalLocation(tile[i, j].WorldLocation.X - map.WorldLocation.X,
                        tile[i, j].WorldLocation.Y - map.WorldLocation.Y,
                        tileSizeX, tileSizeY);
                }
            }
        }
        //타워의 위치 계산
        public void CalculateTowerLocate(int i, int j)
        {
            ContentManager content = ScreenManager.Game.Content;
            InstallCard[InstallCard.Count - 1].Tower.LoadContent(content);

            int x = tile[i, j].WorldLocation.X + (tile[i, j].WorldLocation.Width -
                InstallCard[InstallCard.Count - 1].Tower.TowerTexture.Width) / 2;
            int y = tile[i, j].WorldLocation.Y + tile[i, j].WorldLocation.Height -
                InstallCard[InstallCard.Count - 1].Tower.TowerTexture.Height;

            InstallCard[InstallCard.Count - 1].Tower.WorldLocation =
                new Rectangle(x, y,
                    InstallCard[InstallCard.Count - 1].Tower.TowerTexture.Width,
                    InstallCard[InstallCard.Count - 1].Tower.TowerTexture.Height);
        }

        #endregion
    }
}
